package cn.iocoder.yudao.module.wms.controller.admin.otherin;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.wms.dal.dataobject.doc.DocDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.otherin.OtherInDDO;
import cn.iocoder.yudao.module.wms.service.doc.DocService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.wms.controller.admin.otherin.vo.*;
import cn.iocoder.yudao.module.wms.dal.dataobject.otherin.OtherInDO;
import cn.iocoder.yudao.module.wms.service.otherin.OtherInService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Tag(name = "管理后台 - 通用入库单")
@RestController
@RequestMapping("/wms/other-in")
@Validated
public class OtherInController {

    @Resource
    private OtherInService otherInService;
    @Resource
    private DocService docService;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private DeptApi deptApi;

    @PostMapping("/create")
    @Operation(summary = "创建通用入库单")
    @PreAuthorize("@ss.hasPermission('wms:other-in:create')")
    public CommonResult<Long> createOtherIn(@Valid @RequestBody OtherInSaveReqVO createReqVO) {
        return success(otherInService.createOtherIn(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新通用入库单")
    @PreAuthorize("@ss.hasPermission('wms:other-in:update')")
    public CommonResult<Boolean> updateOtherIn(@Valid @RequestBody OtherInSaveReqVO updateReqVO) {
        otherInService.updateOtherIn(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除通用入库单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('wms:other-in:delete')")
    public CommonResult<Boolean> deleteOtherIn(@RequestParam("id") Long id) {
        otherInService.deleteOtherIn(id);
        return success(true);
    }

    @PutMapping("/approve")
    @Operation(summary = "审核通用入库单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('wms:other-in:approve')")
    public CommonResult<Boolean> approveOtherIn(@RequestParam("id") Long id) {
        otherInService.approveOtherIn(id);
        return success(true);
    }

    @PutMapping("/cancel")
    @Operation(summary = "撤审通用入库单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('wms:other-in:cancel')")
    public CommonResult<Boolean> cancelOtherIn(@RequestParam("id") Long id) {
        otherInService.cancelOtherIn(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得通用入库单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('wms:other-in:query')")
    public CommonResult<OtherInRespVO> getOtherIn(@RequestParam("id") Long id) {
        OtherInDO otherIn = otherInService.getOtherIn(id);
        BeanUtils.toBean(otherIn, OtherInRespVO.class);
        return success(BeanUtils.toBean(otherIn, OtherInRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得通用入库单分页")
    @PreAuthorize("@ss.hasPermission('wms:other-in:query')")
    public CommonResult<PageResult<OtherInRespVO>> getOtherInPage(@Valid OtherInPageReqVO pageReqVO) {
        PageResult<OtherInDO> pageResult = otherInService.getOtherInPage(pageReqVO);
        PageResult<OtherInRespVO> respVOS = BeanUtils.toBean(pageResult, OtherInRespVO.class);
        if (CollectionUtil.isNotEmpty(respVOS.getList())) {
            //提取单据类型
            Set<Long> docIds = CollectionUtils.convertSet(respVOS.getList(), OtherInRespVO::getDocId);
            List<DocDO> docList = docService.getDocList(docIds);
            Map<Long, DocDO> docMap = CollectionUtils.convertMap(docList, DocDO::getId);
            //提取制单人与审核人
            Set<Long> userIds = CollectionUtils.convertSet(respVOS.getList(), OtherInRespVO::getOperateUser);
            Set<Long> approveUserIds = CollectionUtils.convertSet(respVOS.getList(), OtherInRespVO::getApproveUser);
            userIds.addAll(approveUserIds);
            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIds);
            Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId);
            //提取部门
            Set<Long> deptIds = CollectionUtils.convertSet(respVOS.getList(), OtherInRespVO::getOperateDept);
            List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
            Map<Long, DeptRespDTO> deptMap = CollectionUtils.convertMap(deptList, DeptRespDTO::getId);
            //组装数据
            respVOS.getList().forEach(respVO -> {
                DocDO doc = docMap.get(respVO.getDocId());
                if (ObjectUtil.isNotEmpty(doc)) {
                    respVO.setDocName(doc.getName());
                }
                AdminUserRespDTO operateUser = userMap.get(respVO.getOperateUser());
                if (ObjectUtil.isNotEmpty(operateUser)) {
                    respVO.setOperateUserName(operateUser.getNickname());
                }
                AdminUserRespDTO approveUser = userMap.get(respVO.getApproveUser());
                if (ObjectUtil.isNotEmpty(approveUser)) {
                    respVO.setApproveUserName(approveUser.getNickname());
                }
                DeptRespDTO operateDept = deptMap.get(respVO.getOperateDept());
                if (ObjectUtil.isNotEmpty(operateDept)) {
                    respVO.setOperateDeptName(operateDept.getName());
                }
            });
        }
        return success(respVOS);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出通用入库单 Excel")
    @PreAuthorize("@ss.hasPermission('wms:other-in:export')")
    @OperateLog(type = EXPORT)
    public void exportOtherInExcel(@Valid OtherInPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OtherInDO> list = otherInService.getOtherInPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "通用入库单.xls", "数据", OtherInRespVO.class,
                        BeanUtils.toBean(list, OtherInRespVO.class));
    }

    // ==================== 子表（通用入库单身） ====================

    @GetMapping("/other-in-d/list-by-head-id")
    @Operation(summary = "获得通用入库单身列表")
    @Parameter(name = "headId", description = "单头")
    @PreAuthorize("@ss.hasPermission('wms:other-in:query')")
    public CommonResult<List<OtherInDDO>> getOtherInDListByHeadId(@RequestParam("headId") Long headId) {
        return success(otherInService.getOtherInDListByHeadId(headId));
    }

}